import { _decorator, Asset, assetManager, AssetManager, Component, Node } from 'cc';
const { ccclass, property } = _decorator;

export default class ResManager extends Component {
    private static _instance;

    static get instance(): ResManager{
        if(this._instance == null){
            this._instance = new ResManager();
        }
        return this._instance
    }


    loadedBundle: Map<string, AssetManager.Bundle> = new Map<string, AssetManager.Bundle>()
    loadedAsset: Map<string, any> = new Map<string, any>();


    loadBundle(name:string): Promise<AssetManager.Bundle>{
        return new Promise((resolve,reject) => {
            if(this.loadedBundle.has(name)){
                resolve(this.loadedBundle.get(name))
                return
            }

            assetManager.loadBundle(name, (err, ab:AssetManager.Bundle) => {
                // assetManager.removeBundle(ab);
                this.loadedBundle.set(name, ab)
                resolve(ab)
            });
        })
    }

    loadAsset<T extends Asset>(ab:AssetManager.Bundle ,name:string): Promise<T>{
        return new Promise((resolve,reject) => {
            let url = ab.name + '/' + name
            if(this.loadedAsset.has(url)){
               
                resolve(this.loadedAsset.get(url))
                return
            }
            
            ab.load<T>(name, (err, asset:T) => {
              
                this.loadedAsset.set(url, asset);
                resolve(asset)
            })
        })
    }

    async loadAssetByUrl<T extends Asset>(url:string){
        let adName = url.substring(0, url.indexOf('/'))
        let assetName = url.substring(url.indexOf('/') + 1)
        let ab = await this.loadBundle(adName)
        let assert =  await this.loadAsset<T>(ab, assetName)
        return assert
    }
}


